export = {}
/*
  存在一种特殊的非计算的常量枚举成员的子集：字面量枚举成员
  如果枚举值里所有成员的值都是字面量类型的值，那么这个枚举的每个成员和枚举值本身都可以作为类型来使用

  ，先来看下满足条件的枚举成员的值有哪些：

  + 不带初始值的枚举成员，例如enum E { A }
  + 值为字符串字面量，例如enum E { A = ‘a’ }
  + 值为数值字面量，或者带有-符号的数值字面量，例如enum E { A = 1 }、enum E { A = -1 }

  当我们的枚举值的所有成员的值都是上面这三种情况的时候，枚举值和成员就可以作为类型来用
  比如let x:E,则x可以是满足E这个枚举类型里任一枚举成员类型的数据
*/

/** 1.枚举成员类型*/
//我们可以把符合条件的枚举值的成员作为类型来使用，来看例子：
// enum Animal {
//   Dog = 1,
//   Cat = 2
// }
// interface Dog {
//   type: Animal.Dog; // 这里使用Animal.Dog作为类型，指定接口Dog的必须有一个type字段，且类型为Animal.Dog
// }
// interface Cat {
//   type: Animal.Cat; // 这里同上
// }
// let cat1: Cat = {
//   type: Animal.Dog // error [ts] 不能将类型“Animal.Dog”分配给类型“Animal.Cat”
// };
// //√ ↓
// let dog: Dog = {
//   type: Animal.Dog
// };



/** 2.联合枚举类型*/
//当我们的枚举值符合条件时，这个枚举值就可以看做是一个包含所有成员的联合类型，先来看例子：
enum Status {
  Off,
  On
}
interface Light {
  status: Status;
}
enum Animal {
  Dog = 1,
  Cat = 2
}
const light1: Light = {
  status: Animal.Dog // error 不能将类型“Animal.Dog”分配给类型“Status”
};
const light2: Light = {
  status: Status.Off
};
const light3: Light = {
  status: Status.On
};
/* ↑
上面例子定义接口 Light 的 status 字段的类型为枚举值 Status，那么此时 status 的属性值必须为 Status.Off 和 Status.On 中的一个，也就是相当于status: Status.Off | Status.On。*/

//通过联合枚举，类型系统能够利用这样一个事实，它可以知道枚举里的值的集合。 因此，TypeScript能够捕获在比较值的时候犯的愚蠢的错误。 例如：
enum E {
  Foo,
  Bar,
}

function f(x: E) {
  if (x !== E.Foo || x !== E.Bar) { //TS2367: This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap.
    //             ~~~~~~~~~~~
    // Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'.
  }
}
/* ↑
因为x是E类型,故x要么为E.Foo要么为E.Bar, if (x !== E.Foo || x !== E.Bar) 则总是true的 这个if判断就是没有意义的
*/


/** 关于赋值(枚举类型的兼容性))*/
// 枚举类型与数字类型兼容，并且数字类型与枚举类型兼容
// 不同枚举类型之间是不兼容的

enum H {a, b='a'} // 情况一 都没有初始值
enum F {a = 0, b = 1} // 都是数字
enum G {a='apple',b='banana'} //都是字符串

//枚举类型
let e: H = 3; // ←之所以可以直接赋数字 而不是F.a这样赋值 就是因为 枚举类型与数字类型兼容
let ff: F = 3; //取值可以超出枚举成员的定义 只要类型对即可 但这样做没有意义 正确的写法应该是 let ff: F = F.a or F.b, 否则你为何要使用枚举类型呢？
// E===F // 不同枚举类型间不可以做比较;This condition will always return 'false' since the types 'typeof E' and 'typeof F' have no overlap（交集）.

//枚举值可以赋给数字
enum Colors {Red,Yellow}
let n:number;
n = 1;
n = Colors.Red;

//枚举成员类型
let e1: H.a = 1;
let e2: H.b;
let e3: H.a = 2 ;

//字符串枚举 取值 只能是枚举成员
let g1: G = G.b;
let g2: G.a = G.a;

